package com.yjt.oauth.controller;

import com.alibaba.fastjson.JSONObject;
import com.yjt.common.vo.CommonResult;
import com.yjt.oauth.form.LoginForm;
import com.yjt.oauth.vo.Oauth2TokenVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

/**
 * @author 曾智平
 * @Description: 重写认证token接口
 * @date 2021/5/2516:29
 */
@RestController
@RequestMapping("/oauth")
@Api(tags = "登录认证")
public class LoginController {
    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    /**
     * 登录认证功能
     * @param principal
     * @param loginForm
     * @return
     * @throws HttpRequestMethodNotSupportedException
     */
    @ApiOperation(value = "登录认证功能", notes = "返回JSONObject")
    @RequestMapping(value = "/token", method = RequestMethod.POST)
    public CommonResult<Oauth2TokenVO> postAccessToken(Principal principal, @RequestBody @Validated LoginForm loginForm
    ) throws HttpRequestMethodNotSupportedException {
        //构造所需参数
        Map<String, String> parameters = new HashMap<>();
        parameters.put("username", JSONObject.toJSONString(loginForm));
        parameters.put("password", loginForm.getPassword());
        parameters.put("grant_type", loginForm.getGrantType());
        //生成token
        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        Oauth2TokenVO oauth2TokenDto = Oauth2TokenVO.builder()
                .token(oAuth2AccessToken.getValue())
                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())
                .expiresIn(oAuth2AccessToken.getExpiresIn() + 259200)
                .tokenHead("Bearer ").build();
        return CommonResult.success(oauth2TokenDto);
    }

    @DeleteMapping("/logout")
    @ApiOperation(value = "退出功能", notes = "返回JSONObject")
    @ApiImplicitParam(name = "Authorization", value = "请求头默认Basic token")
    public CommonResult logout(@RequestHeader(value = HttpHeaders.AUTHORIZATION, required = false) String authHeader) {
        if (authHeader == null || authHeader.isEmpty()) {
            return CommonResult.success("退出成功");
        }
        String tokenValue = authHeader.replace(OAuth2AccessToken.BEARER_TYPE, "").trim();
        OAuth2AccessToken accessToken = tokenStore.readAccessToken(tokenValue);
        if (accessToken == null || accessToken.getValue() == null || accessToken.getValue().isEmpty()) {
            return CommonResult.success("退出成功");
        }
        // 清空 access token
        tokenStore.removeAccessToken(accessToken);
        // 清空 refresh token
        OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
        tokenStore.removeRefreshToken(refreshToken);
        return CommonResult.success("退出成功");
    }

}
